home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Monster Media 1996 #15
/
Monster Media Number 15 (Monster Media)(July 1996).ISO
/
prog_c
/
recio214.zip
/
RFIX.C
< prev
next >
Wrap
C/C++ Source or Header
|
1996-06-14
|
8KB
|
213 lines
/****************************************************************************
MODULE: rfix.c
PURPOSE: recio functions used to fix bad data
COPYRIGHT: (C) 1994-1996, William Pierpoint
COMPILER: Borland C Version 3.1
OS: MSDOS Version 6.2
VERSION: 2.14
RELEASE: June 14, 1996
*****************************************************************************
These functions make an educated guess at fixing bad data. They are used in
the test programs. They are not necessarily appropriate for your application.
Mnemonics are as follows:
Single letter (fix functions)
-----------------------------
b - base (prefix)
c - character (suffix)
d - double (suffix)
f - float (suffix)
i - integer (suffix)
l - long (suffix)
r - record pointer (first letter)
t - time_t (suffix)
u - unsigned (suffix)
Example: rbfixui() takes two arguments, record pointer and base (radix) of
number, and fixes an unsigned integer.
*****************************************************************************/
#include <ctype.h>
#include <float.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "recio.h"
extern int str2c(const char *nptr, char **endptr);
extern unsigned long str2ul(const char *nptr, char **endptr, int base);
/* these values initialized here, computed in rfixt function */
time_t mintime_t=0; /* minimum value for time_t */
time_t maxtime_t=0; /* maximum value for time_t */
/* clip value v between lower l and upper u bounds */
#define range(l, v, u) (min(max((l),(v)),(u)))
#define rtmfmt(rp) ((rp)->r_tmfmt)
/****************************************************************************/
static char * /* return pointer to string */
ctoa( /* convert char to string */
int ch, /* character to convert */
char *str) /* string buffer to use */
/****************************************************************************/
{
if (ch > 0) str[0] = ch;
else str[0] = '\0';
str[1] = '\0';
return str;
}
/****************************************************************************/
static char * /* return pointer to string */
tdtoa( /* convert floating point number to string */
double d, /* number to convert */
char *str, /* string buffer to use */
int dig) /* number of significant digits */
/****************************************************************************/
{
char *sp=str;
/* get one digit more than number of significant digits */
sprintf(str, "%.*E", dig, d);
/* truncate last digit of significand */
while (*sp != 'E') sp++;
memmove(sp-1, sp, strlen(sp)+1);
return str;
}
/****************************************************************************/
static int /* return 1 if neg zero, 0 otherwise */
isnegzero( /* does field buffer contain negative zero */
REC *rp) /* record pointer */
/****************************************************************************/
{
int negzero=0; /* 0=not neg zero; 1=neg zero */
char *sp; /* pointer to field buffer */
sp = rflds(rp);
while (isspace(*sp)) sp++;
if (*sp++ != '-') goto done;
while (*sp == '0') sp++;
if (*sp < '0' || *sp > '9') negzero++;
done:
return negzero;
}
/****************************************************************************/
void rbfixi(REC *rp, int base)
/****************************************************************************/
{
long l = range(INT_MIN, strtol(rflds(rp), NULL, base), INT_MAX);
if (isnegzero(rp)) rsetfldstr(rp, "0");
else rsetfldstr(rp, ltoa(l, _r_nsbuf, base));
}
/****************************************************************************/
void rbfixui(REC *rp, int base)
/****************************************************************************/
{
unsigned long ul = min(str2ul(rflds(rp), NULL, base), UINT_MAX);
rsetfldstr(rp, ultoa(ul, _r_nsbuf, base));
}
/****************************************************************************/
void rbfixl(REC *rp, int base)
/****************************************************************************/
{
long l = range(LONG_MIN, strtol(rflds(rp), NULL, base), LONG_MAX);
if (isnegzero(rp)) rsetfldstr(rp, "0");
else rsetfldstr(rp, ltoa(l, _r_nsbuf, base));
}
/****************************************************************************/
void rbfixul(REC *rp, int base)
/****************************************************************************/
{
unsigned long ul= min(str2ul(rflds(rp), NULL, base), ULONG_MAX);
rsetfldstr(rp, ultoa(ul, _r_nsbuf, base));
}
/****************************************************************************/
void rfixi(REC *rp)
/****************************************************************************/
{
rbfixi(rp, 10);
}
/****************************************************************************/
void rfixui(REC *rp)
/****************************************************************************/
{
rbfixui(rp, 10);
}
/****************************************************************************/
void rfixl(REC *rp)
/****************************************************************************/
{
rbfixl(rp, 10);
}
/****************************************************************************/
void rfixul(REC *rp)
/****************************************************************************/
{
rbfixul(rp, 10);
}
/****************************************************************************/
void rfixf(REC *rp)
/****************************************************************************/
{
double d = range(-FLT_MAX, strtod(rflds(rp), NULL), FLT_MAX);
if (d > -FLT_MIN && d < FLT_MIN) d=0.0; /* zero if underflow */
rsetfldstr(rp, tdtoa((float) d, _r_nsbuf, FLT_DIG));
}
/****************************************************************************/
void rfixd(REC *rp)
/****************************************************************************/
{
double d = strtod(rflds(rp), NULL);
if (d > -DBL_MIN && d < DBL_MIN) d=0.0; /* zero if underflow */
rsetfldstr(rp, tdtoa(d, _r_nsbuf, DBL_DIG));
}
/****************************************************************************/
void rfixc(REC *rp)
/****************************************************************************/
{
int ch = str2c(rflds(rp), NULL);
rsetfldstr(rp, ctoa(ch, _r_nsbuf));
}
/****************************************************************************/
void rfixt(REC *rp)
/****************************************************************************/
{
struct tm mintm; /* tm for TIME_T_MIN */
struct tm maxtm; /* tm for TIME_T_MAX */
struct tm curtm; /* tm representation of current time field */
char s[NSBUFSIZ]; /* string representation of time */
curtm = sftotm(rflds(rp), rtmfmt(rp));
mintm = timetotm(TIME_T_MIN);
maxtm = timetotm(TIME_T_MAX);
if (curtm.tm_year >= maxtm.tm_year) {
if (!strftime(s, NSBUFSIZ-1, rtmfmt(rp), &maxtm)) {
rseterr(rp, R_EINVAL); /* insufficient size for s[] */
}
} else {
if (!strftime(s, NSBUFSIZ-1, rtmfmt(rp), &mintm)) {
rseterr(rp, R_EINVAL); /* insufficient size for s[] */
}
}
rsetfldstr(rp, s);
}